package weavingdraft;
import java.util.Observable;

/**
 * The background storage for the WeavingDraft object. 
 * 
 * @author Justin Wong
 *
 */
public class WeavingDraft extends Observable{
	/**
	 * The array for the thread grid. 
	 */
	private int[] threading_grid;
	/**
	 * The array for the pedalling panel. 
	 */
	private int[] pedalling_grid;
	/**
	 * The double array for the tieup.
	 */
	private int[][] tieUp;
	/**
	 * The double array for the pattern. 
	 */
	private int[][] pattern;
	/**
	 * The length of the long side. 
	 */
	private int long_side;
	/**
	 * The short side of the panels. 
	 */
	private int short_side;
	
	/**
	 * Creates the WeavingDraft objects. 
	 */
	public WeavingDraft(){
		short_side = 4;
		long_side = 16;
		threading_grid = new int[long_side];
		pedalling_grid = new int[long_side];
		tieUp = new int[short_side][short_side];
		pattern = new int[long_side][long_side];
		initilizeArrays();
	}
	/**
	 * Initilizes the arrays to either 0, 1 or -1.
	 */
	private void initilizeArrays(){
		for(int i = 0; i < threading_grid.length ; i++){
			threading_grid[i] = -1;
		}
		for(int i = 0; i < pedalling_grid.length; i++){
			pedalling_grid[i] = -1;
		}
		for(int i = 0; i < short_side; i++){
			for(int j = 0; j < short_side; j++){
				tieUp[i][j] = 0;
			}
		}
		for(int i = 0; i < long_side; i++){
			for(int j = 0; j < long_side; j++){
				pattern[i][j] = 0;
			}
		}
	}
	/**
	 * Sets the PedallingGrid at the specific location. 
	 * 
	 * @param the_row the row. 
	 * @param the_column the column.
	 */
	public void setPedallingGrid(int the_row, int the_column){
		if(pedalling_grid[the_row] > -1){
			updatePedalling(the_row, pedalling_grid[the_row], 0);
		}
		pedalling_grid[the_row] = the_column;
		updatePedalling(the_row, pedalling_grid[the_row], 1);
	}
	/**
	 * Deletes the pedal at a specific location. 
	 * 
	 * @param the_row the row to refer to. 
	 * @param the_column the column to refer to. 
	 */
	public void deletePedal(int the_row, int the_column){
		pedalling_grid[the_row] = -1;
		updatePedalling(the_row, the_column, 0);
	}
	/**
	 * Updates the pedalling grid. 
	 * @param the_row the row to update. 
	 * @param the_column the column to update. 
	 * @param the_change the value to be assigned. 
	 */
	private void updatePedalling(int the_row, int the_column, int the_change){
		for(int i = 0; i < short_side; i++){
			if(tieUp[i][the_column] == 1){
				for(int j = 0; j < threading_grid.length; j++){
					if(threading_grid[j] == i){
						pattern[the_row][j] = the_change;
					}
				}
			}
		}
		setChanged();
		notifyObservers();
		
	}
	/**
	 * Sets the thread at the specific row and column. 
	 * 
	 * @param the_row the row. 
	 * @param the_column the column. 
	 */
	public void setThreading(int the_row, int the_column){
		if(threading_grid[the_column] > -1){
			deleteThread(the_row, the_column);
			
		}
		threading_grid[the_column] = the_row;
		updateThreading(the_row, the_column);
	}
	/**
	 * The Thread to delete from. 
	 * @param the_row the row to delete from. 
	 * @param the_column the column to delete from. 
	 */
	public void deleteThread(int the_row, int the_column){
		for(int i = 0; i < long_side; i++){
			if(pattern[i][the_column] == 1){
				pattern[i][the_column] = 0;
			}
		}
		threading_grid[the_column] = -1;
		setChanged();
		notifyObservers();
	}
	/**
	 * Updates the threading grid. 
	 * @param the_row the row that needs to be updated. 
	 * @param the_column the row that need to be updates. 
	 */
	private void updateThreading(int the_row, int the_column){
		for(int i = 0; i < short_side; i++){
			if(tieUp[the_row][i] == 1){
				for(int j = 0; j < long_side; j++){
					if(pedalling_grid[j] == i){
						pattern[j][the_column] = 1;
					}
				}
			}
		}
		setChanged();
		notifyObservers();
	}
	/**
	 * Sets the tieup and the changes to it. 
	 * @param the_row the row to change. 
	 * @param the_column the column to change. 
	 */
	public void setTieUp(int the_row, int the_column){
		tieUp[the_row][the_column] = 1;
		changeTieUp(the_row, the_column, 1);

	}
	/**
	 * Deletes the tieup given the row and column. 
	 * @param the_row the row to change. 
	 * @param the_column the column to be changed.
	 */
	public void deleteTieUp(int the_row, int the_column){
		tieUp[the_row][the_column] = 0;
		changeTieUp(the_row, the_column, 0);
	}
	/**
	 * Changes the tie up at the designed positions.
	 * @param the_row the row to be changed. 
	 * @param the_column the column to be changed. 
	 * @param the_change how to change the column. 
	 */
	private void changeTieUp(int the_row, int the_column, int the_change){
		for(int i = 0; i < pedalling_grid.length; i++){
			if(pedalling_grid[i] == the_column){
				for(int j = 0; j < threading_grid.length; j++){
					if(threading_grid[j] == the_row){
						pattern[i][j] = the_change;
					}
				}
			}
		}
		setChanged();
		notifyObservers();
	}
	/**
	 * Returns the pattern at the specific row and column. 
	 * @param row the row to get the pattern from. 
	 * @param column the column to get the pattern from. 
	 * @return returns the number at the row and pattern.
	 */
	public int getPattern(int row, int column){
		return pattern[row][column];
	}
	/**
	 * Returns the draft pattern. 
	 * @return the pattern.
	 */
	public int[][] getdraft() {
		return pattern;
	}
	/**
	 * Gets the short side of the draft. 
	 * @return the short side information. 
	 */
	public int getShortside(){
		return short_side;
	}
	/**
	 * Gets the longside of the draft. 
	 * @return the long side. 
	 */
	public int getLongside(){
		return long_side;
	}
	
	
}
